package
{
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.utils.Dictionary;
	
	import algorithm.DijkstraNoDirctionAlgorithm;
	
	import fl.controls.Button;
	
	public class Dijkstra extends Sprite
	{
		private var points:Array;
		
		private var _pointMap:HashMap;
		
		private var _pointMatrix:Dictionary;
		
		private var _lineModleMap:HashMap;
		
		
		//用来存放基础信息的矩阵（s-e: length）
		private var topuMapMatrix:Dictionary;

		public function Dijkstra()
		{
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			var createToPoBut:Button = new Button();
			createToPoBut.label = "ToPo";
			createToPoBut.addEventListener(MouseEvent.CLICK,onCreateToPoHandler);
			this.addChild(createToPoBut);
			
			var findPathBut:Button = new Button();
			findPathBut.x = 200;
			findPathBut.label = "findPath";
			findPathBut.addEventListener(MouseEvent.CLICK,onFindPathHandler);
			this.addChild(findPathBut);
		}
		
		
		private function onCreateToPoHandler(event:Event):void
		{
			_pointMatrix = new Dictionary();
			_pointMap = new HashMap();
			_lineModleMap = new HashMap();
			points = [];
			createToPo(6);
		}
		
		/**
		 *构建拓扑数据结构 
		 */		
		private function createToPo(num:int):void
		{
			topuMapMatrix = new Dictionary();
			for(var i:int=0;i< num;i++ )
			{
				topuMapMatrix[i] = new Dictionary();
			}
			//
			topuMapMatrix[0][1] = 1;
			topuMapMatrix[0][2] = 2;
			topuMapMatrix[1][3] = 2;
			topuMapMatrix[2][4] = 1;
			topuMapMatrix[3][2] = 3;
			topuMapMatrix[1][4] = 1;
			topuMapMatrix[3][5] = 1;
			topuMapMatrix[4][5] = 1;
			
			//构造起点
			createBall(0,Math.random()*500,Math.random()*400);
			
			//生成路点
			for(var k:int = 0;k<num;k++)
			{
				for(var j:int = 0;j<num;j++)
				{
					if(topuMapMatrix[k] && topuMapMatrix[k][j])
					{
						var distance:Number = (topuMapMatrix[k][j] as Number)*100;
						var sp:MapPoint = _pointMap.get(k) as MapPoint;
						var ex:Number = sp.x + 100;
						var ey:Number = 0;
						if(!_pointMap.get(j))
						{
							ey = Math.sqrt(distance*distance-10000) + sp.y;
							createBall(j,ex,ey);
						}
						drawLine(sp,_pointMap.get(j) as MapPoint,topuMapMatrix[k][j] as Number);
					}
				}
			}
			
		}
		
		private function onFindPathHandler(event:Event):void
		{
			DijkstraNoDirctionAlgorithm.getInstance().createTopoMap(_pointMap,_pointMatrix,points[0] as MapPoint, points[5] as MapPoint,drawPath);
		}
		
		private function createBall(id:int,x:int,y:int):void
		{
			var point:MapPoint = new MapPoint(id,Math.random()*0xFFFFFF);
			point.x = x;
			point.y = y;
			this.addChild(point);
			//生成构造路径用的点集合
			points.push(point);
			//注册点信息
			_pointMap.put(point.mapId,point);
		}
		
		private function drawLine(sourcePoint:MapPoint,targetPoint:MapPoint,weight:Number):void
		{
				var mapLineId:int = UintToByte.intToByte(sourcePoint.mapId,targetPoint.mapId);
				var line:MapLine = new MapLine(mapLineId,Point.distance(new Point(sourcePoint.x,sourcePoint.y),new Point(targetPoint.x,targetPoint.y)));
				var angle:Number = (Math.atan2((targetPoint.y- sourcePoint.y),(targetPoint.x- sourcePoint.x))/Math.PI)*180;
				line.rotation = angle;
				line.x = sourcePoint.x;
				line.y = sourcePoint.y;
				this.addChild(line);
				_lineModleMap.put(UintToByte.intToByte(sourcePoint.mapId,targetPoint.mapId),line);
				
				var sourcePointMatrix:Dictionary = _pointMatrix[sourcePoint.mapId] as Dictionary;
				if(!sourcePointMatrix)
				{
					sourcePointMatrix = new Dictionary();
					_pointMatrix[sourcePoint.mapId] = sourcePointMatrix;
				}
				sourcePointMatrix[targetPoint.mapId] = weight;//将路径放入字典
		}
		
		public function drawPath(path:Array):void
		{
			for(var i:int = 0;i<path.length-1;i++)
			{
				var sId:int = path[i];
				var eId:int = path[i+1];
				
				(_lineModleMap.get(UintToByte.intToByte(sId,eId)) as MapLine).markFindPathLine();
			}
		}
		
	}
}